import axios, {
  AxiosRequestConfig,
  AxiosResponse,
  CancelTokenSource,
} from 'axios';

class HttpClient {
  private cancelTokenSource: CancelTokenSource;

  constructor() {
    this.cancelTokenSource = axios.CancelToken.source();
  }

  /**
   * 发送 GET 请求
   * @param url 请求的 URL
   * @param params 请求参数
   * @param headers 请求头
   * @returns 返回请求的结果
   */
  public async get<T>(
    url: string,
    params?: Record<string, any>,
    headers?: Record<string, string>,
  ): Promise<T> {
    const config: AxiosRequestConfig = {
      params,
      headers,
      cancelToken: this.cancelTokenSource.token,
    };

    try {
      const response: AxiosResponse<T> = await axios.get(url, config);
      return response.data;
    } catch (error) {
      this.handleError(error);
      throw error;
    }
  }

  /**
   * 发送 POST 请求
   * @param url 请求的 URL
   * @param data 请求体数据
   * @param headers 请求头
   * @returns 返回请求的结果
   */
  public async post<T>(
    url: string,
    data?: Record<string, any>,
    headers?: Record<string, string>,
  ): Promise<T> {
    const config: AxiosRequestConfig = {
      headers,
      cancelToken: this.cancelTokenSource.token,
    };

    try {
      const response: AxiosResponse<T> = await axios.post(url, data, config);
      return response.data;
    } catch (error) {
      this.handleError(error);
      throw error;
    }
  }

  /**
   * 取消当前请求
   */
  public cancelRequest(): void {
    this.cancelTokenSource.cancel('Request canceled by the user.');
    // 重新初始化 cancelTokenSource，以便下次请求使用
    this.cancelTokenSource = axios.CancelToken.source();
  }

  /**
   * 处理请求错误
   * @param error 错误对象
   */
  private handleError(error: any): void {
    if (axios.isCancel(error)) {
      console.log('Request canceled:', error.message);
    } else if (error.response) {
      // 服务器返回了错误状态码
      console.error('Request failed with status:', error.response.status);
      console.error('Response data:', error.response.data);
    } else if (error.request) {
      // 请求已发出，但没有收到响应
      console.error('No response received:', error.request);
    } else {
      // 其他错误
      console.error('Request setup error:', error.message);
    }
  }
}

export default HttpClient;
